Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
@material/tabs
Advanced tools
The MDC Tabs component contains components which are used to create spec-aligned tabbed navigation components adhering to the Material Design tabs guidelines. These components are:
mdc-tab
elementsmdc-tab-bar
that overflows its containernpm install --save @material/tabs
mdc-tab-bar
can be used as a CSS only component, or a more dynamic JavaScript
component.
There are also three different permutations of tab labels. These include text, icon-only, and text with icon. An example of each is available on the demo site.
<nav id="basic-tab-bar" class="mdc-tab-bar">
<a class="mdc-tab mdc-tab--active" href="#one">Home</a>
<a class="mdc-tab" href="#two">Merchandise</a>
<a class="mdc-tab" href="#three">About Us</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
<nav class="mdc-tab-bar mdc-tab-bar--icon-tab-bar">
<a class="mdc-tab mdc-tab--active" href="#recents">
<i class="material-icons mdc-tab__icon" aria-label="Recents">phone</i>
</a>
<a class="mdc-tab" href="#favorites">
<i class="material-icons mdc-tab__icon" aria-label="Favorites">favorite</i>
</a>
<a class="mdc-tab" href="#nearby">
<i class="material-icons mdc-tab__icon" aria-label="nearby">person_pin</i>
</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
<nav id="icon-text-tab-bar" class="mdc-tab-bar mdc-tab-bar--icons-with-text">
<a class="mdc-tab mdc-tab--with-icon-and-text mdc-tab--active" href="#recents">
<i class="material-icons mdc-tab__icon" aria-hidden="true">phone</i>
<span class="mdc-tab__icon-text">Recents</span>
</a>
<a class="mdc-tab mdc-tab--with-icon-and-text" href="#favorites">
<i class="material-icons mdc-tab__icon" aria-hidden="true">favorite</i>
<span class="mdc-tab__icon-text">Favorites</span>
</a>
<a class="mdc-tab mdc-tab--with-icon-and-text" href="#nearby">
<i class="material-icons mdc-tab__icon" aria-hidden="true">person_pin</i>
<span class="mdc-tab__icon-text">Nearby</span>
</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
Tab Bars will reverse the order of their tabs if they are placed within an
ancestor element with attribute dir="rtl"
.
<html dir="rtl">
<!--...-->
<nav id="basic-tab-bar" class="mdc-tab-bar">
<a class="mdc-tab mdc-tab--active" href="#one">Home</a>
<a class="mdc-tab" href="#two">Merchandise</a>
<a class="mdc-tab" href="#three">About Us</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
</html>
Like other MDC-Web components, tabs support dark mode either when an
mdc-tab-bar--theme-dark
class is attached to the root element, or the element has
an ancestor with class mdc-theme--dark
.
<html class="mdc-theme--dark">
<!-- ... -->
<nav id="basic-tab-bar" class="mdc-tab-bar">
<a class="mdc-tab mdc-tab--active" href="#one">Home</a>
<a class="mdc-tab" href="#two">Merchandise</a>
<a class="mdc-tab" href="#three">About Us</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
</html>
While facilitating the view switching is left up to the developer, the demo site provides a minimal example of how to do so using JavaScript, also shown below.
<section id="dynamic-demo-toolbar">
<nav id="dynamic-tab-bar" class="mdc-tab-bar mdc-tab-bar--indicator-accent" role="tablist">
<a role="tab" aria-controls="panel-1"
class="mdc-tab mdc-tab--active" href="#panel-1">Item One</a>
<a role="tab" aria-controls="panel-2"
class="mdc-tab" href="#panel-2">Item Two</a>
<a role="tab" aria-controls="panel-3"
class="mdc-tab" href="#panel-3">Item Three</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
</section>
<section>
<div class="panels">
<p class="panel active" id="panel-1" role="tabpanel" aria-hidden="false">Item One</p>
<p class="panel" id="panel-2" role="tabpanel" aria-hidden="true">Item Two</p>
<p class="panel" id="panel-3" role="tabpanel" aria-hidden="true">Item Three</p>
</div>
<div class="dots">
<a class="dot active" data-trigger="panel-1" href="#panel-1"></a>
<a class="dot" data-trigger="panel-2" href="#panel-2"></a>
<a class="dot" data-trigger="panel-3" href="#panel-3"></a>
</div>
</section>
var dynamicTabBar = window.dynamicTabBar = new mdc.tabs.MDCTabBar(document.querySelector('#dynamic-tab-bar'));
var dots = document.querySelector('.dots');
var panels = document.querySelector('.panels');
dynamicTabBar.preventDefaultOnClick = true;
function updateDot(index) {
var activeDot = dots.querySelector('.dot.active');
if (activeDot) {
activeDot.classList.remove('active');
}
var newActiveDot = dots.querySelector('.dot:nth-child(' + (index + 1) + ')');
if (newActiveDot) {
newActiveDot.classList.add('active');
}
}
function updatePanel(index) {
var activePanel = panels.querySelector('.panel.active');
if (activePanel) {
activePanel.classList.remove('active');
}
var newActivePanel = panels.querySelector('.panel:nth-child(' + (index + 1) + ')');
if (newActivePanel) {
newActivePanel.classList.add('active');
}
}
dynamicTabBar.listen('MDCTabBar:change', function ({detail: tabs}) {
var nthChildIndex = tabs.activeTabIndex;
updatePanel(nthChildIndex);
updateDot(nthChildIndex);
});
dots.addEventListener('click', function (evt) {
if (!evt.target.classList.contains('dot')) {
return;
}
evt.preventDefault();
var dotIndex = [].slice.call(dots.querySelectorAll('.dot')).indexOf(evt.target);
if (dotIndex >= 0) {
dynamicTabBar.activeTabIndex = dotIndex;
}
updatePanel(dotIndex);
updateDot(dotIndex);
})
mdc-tab-bar
ships with css for styling a tab layout according to the Material
Design spec. To use CSS only tab bars, simply use the available class names.
Note the available mdc-tab--active
modifier class. This is used to denote the
currently active tab.
<nav class="mdc-tab-bar">
<a class="mdc-tab mdc-tab--active" href="#one">Item One</a>
<a class="mdc-tab" href="#two">Item Two</a>
<a class="mdc-tab" href="#three">Three</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
mdc-tab-bar
ships with a Component/Foundation combo for ingesting instances of mdc-tab
(a tab).
mdc-tab-bar
uses its initialize()
method call a factory function which gathers and instantiates
any tab elements that are children of the mdc-tab-bar
root element.
import {MDCTab, MDCTabFoundation} from '@material/tabs';
import {MDCTabBar, MDCTabBarFoundation} from '@material/tabs';
const mdcTabs = require('@material/tabs');
const MDCTab = mdcTabs.MDCTab;
const MDCTabFoundation = mdcTabs.MDCTabFoundation;
const MDCTabBar = mdcTabs.MDCTabBar;
const MDCTabBarFoundation = mdcTabs.MDCTabBarFoundation;
require(['path/to/@material/tabs'], mdcTabs => {
const MDCTab = mdcTabs.MDCTab;
const MDCTabFoundation = mdcTabs.MDCTabFoundation;
const MDCTabBar = mdcTabs.MDCTabBar;
const MDCTabBarFoundation = mdcTabs.MDCTabBarFoundation;
});
const MDCTab = mdc.tabs.MDCTab;
const MDCTabFoundation = mdc.tabs.MDCTabFoundation;
const MDCTabBar = mdc.tabs.MDCTabBar;
const MDCTabBarFoundation = mdc.tabs.MDCTabBarFoundation;
If you do not care about retaining the component instance for the tabs, simply
call attachTo()
and pass it a DOM element.
mdc.tabs.MDCTabBar.attachTo(document.querySelector('#my-mdc-tab-bar'));
Tabs can easily be initialized using their default constructors as well, similar
to attachTo
. This process involves a factory to create an instance of MDCTab
from each tab Element inside of the mdc-tab-bar
node during the initialization phase
of MDCTabBar
, e.g.:
<nav id="my-mdc-tab-bar" class="mdc-tab-bar">
<a class="mdc-tab mdc-tab--active" href="#one">Item One</a>
<a class="mdc-tab" href="#two">Item Two</a>
<a class="mdc-tab" href="#three">Three</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
import {MDCTabBar, MDCTabBarFoundation} from '@material/tabs';
const tabBar = new MDCTabBar(document.querySelector('#my-mdc-tab-bar'));
mdc-tab-bar-scroller
ships with a Component/Foundation combo which wraps instances of mdc-tab-bar
. mdc-tab-bar-scroller
uses its initialize()
method call a factory function which gathers and instantiates any tab bar elements that are children of the mdc-tab-bar-scroller
root element.
The anatomy of mdc-tab-bar-scroller
includes an instance of mdc-tab-bar
, RTL-aware forward and back indicators which, when actioned on, move the tab bar left and right, and a scroll frame. The scroll frame is the parent element of the tab bar, and serves to mask the tabs in the tab bar when they overflow the available width.
import {MDCTab, MDCTabFoundation} from '@material/tabs';
import {MDCTabBar, MDCTabBarFoundation} from '@material/tabs';
import {MDCTabBarScroller, MDCTabBarFoundationScroller} from '@material/tabs';
const mdcTabs = require('@material/tabs');
const MDCTab = mdcTabs.MDCTab;
const MDCTabFoundation = mdcTabs.MDCTabFoundation;
const MDCTabBar = mdcTabs.MDCTabBar;
const MDCTabBarFoundation = mdcTabs.MDCTabBarFoundation;
const MDCTabBarScroller = mdcTabs.MDCTabBarScroller;
const MDCTabBarScrollerFoundation = mdcTabs.MDCTabBarScrollerFoundation;
require(['path/to/@material/tabs'], mdcTabs => {
const MDCTab = mdcTabs.MDCTab;
const MDCTabFoundation = mdcTabs.MDCTabFoundation;
const MDCTabBar = mdcTabs.MDCTabBar;
const MDCTabBarFoundation = mdcTabs.MDCTabBarFoundation;
const MDCTabBarScroller = mdcTabs.MDCTabBarScroller;
const MDCTabBarScrollerFoundation = mdcTabs.MDCTabBarScrollerFoundation;
});
const MDCTab = mdc.tabs.MDCTab;
const MDCTabFoundation = mdc.tabs.MDCTabFoundation;
const MDCTabBar = mdc.tabs.MDCTabBar;
const MDCTabBarFoundation = mdc.tabs.MDCTabBarFoundation;
const MDCTabBarScroller = mdc.tabs.MDCTabBarScroller;
const MDCTabBarScrollerFoundation = mdc.tabs.MDCTabBarScrollerFoundation;
If you do not care about retaining the component instance for the tabs, simply
call attachTo()
and pass it a DOM element.
mdc.tabs.MDCTabBarScroller.attachTo(document.querySelector('#my-mdc-tab-bar-scroller'));
Tab Bar Scrollers can easily be initialized using their default constructors as well, similar
to attachTo
. This process involves a factory to create an instance of MDCTabBar
from the mdc-tab-bar
Element inside of the mdc-tab-bar-scroller
node during the initialization phase
of MDCTabBarScroller
, e.g.:
<div id="my-tab-bar-scroller" class="mdc-tab-bar-scroller">
<div class="mdc-tab-bar-scroller__indicator mdc-tab-bar-scroller__indicator--back">
<a class="mdc-tab-bar-scroller__indicator__inner material-icons" href="#" aria-label="scroll back button">
navigate_before
</a>
</div>
<div class="mdc-tab-bar-scroller__scroll-frame">
<nav id="my-scrollable-tab-bar" class="mdc-tab-bar mdc-tab-bar-scroller__scroll-frame__tabs">
<a class="mdc-tab mdc-tab--active" href="#one">Item One</a>
<a class="mdc-tab" href="#two">Item Two</a>
<a class="mdc-tab" href="#three">Item Three</a>
<a class="mdc-tab" href="#four">Item Four</a>
<a class="mdc-tab" href="#five">Item Five</a>
<a class="mdc-tab" href="#six">Item Six</a>
<a class="mdc-tab" href="#seven">Item Seven</a>
<a class="mdc-tab" href="#eight">Item Eight</a>
<a class="mdc-tab" href="#nine">Item Nine</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
</div>
<div class="mdc-tab-bar-scroller__indicator mdc-tab-bar-scroller__indicator--forward">
<a class="mdc-tab-bar-scroller__indicator__inner material-icons" href="#" aria-label="scroll forward button">
navigate_next
</a>
</div>
</div>
import {MDCTabBarScroller, MDCTabBarScrollerFoundation} from '@material/tabs';
const tabBarScroller = new MDCTabBarScroller(document.querySelector('#my-mdc-tab-bar-scroller'));
Tab Bar Scrollers can also instantiate any mdc-tab-bar
from a DOM element on the fly using a built in factory function:
import {MDCTabBarScroller, MDCTabBarScrollerFoundation} from '@material/tabs';
const tabBarEl = document.querySelector('#my-mdc-tab-bar');
const scrollerEl = document.querySelector('#my-mdc-tab-bar-scroller');
const tabBarScroller = new MDCTabBarScroller(scrollerEl, undefined, tabBarEl);
This will create an instance of MDC Tab Bar during the initialization phase of Tab Bar Scroller.
Property Name | Type | Description |
---|---|---|
computedWidth | number | (read-only) The width of the tab. |
computedLeft | number | (read-only) The left offset of the tab. |
isActive | boolean | Whether or not the tab is active. Setting this makes the tab active. |
preventDefaultOnClick | boolean | Whether or not the tab will call preventDefault() on an event. Setting this makes the tab call preventDefault() on events. |
Broadcast when a user actions on the tab.
MDC Tab ships with an MDCTabFoundation
class that external frameworks and libraries can
use to integrate the component. As with all foundation classes, an adapter object must be provided.
Method Signature | Description |
---|---|
addClass(className: string) => void | Adds a class to the root element. |
removeClass(className: string) => void | Removes a class from the root element. |
registerInteractionHandler(evt: string, handler: EventListener) => void | Adds an event listener to the root element, for the specified event name. |
deregisterInteractionHandler(evt: string, handler: EventListener) => void | Removes an event listener from the root element, for the specified event name. |
getOffsetWidth() => number | Return the width of the tab |
getOffsetLeft() => number | Return distance between left edge of tab and left edge of its parent element |
notifySelected() => {} | Broadcasts an event denoting that the user has actioned on the tab |
Return the computed width for tab.
Return the computed left offset for tab.
Return true if tab is active.
Set tab to active. If isActive
is true, adds the active modifier class, otherwise removes it.
Return true if the tab prevents the default click action
Sets tabs preventDefaultOnClick
property to the value of the preventDefaultOnClick
argument passed.
Sets computedWidth_
and computedLeft_
for a tab.
Property Name | Type | Description |
---|---|---|
tabs | MDCTab[] | (read-only) An array of the tab bar's instances of MDC Tab. |
activeTab | MDCTab | The currently active tab. Setting this makes the tab active. |
activeTabIndex | number | The index of the currently active tab. Setting this makes the tab at the given index active. |
Broadcast when a user actions on a tab, resulting in a change in the selected tab.
mdc-tab-bar
ships with an MDCTabBarFoundation
class that external frameworks
and libraries can use to integrate the component. As with all foundation
classes, an adapter object must be provided.
Method Signature | Description |
---|---|
addClass(className: string) => void | Adds a class to the root element. |
removeClass(className: string) => void | Removes a class from the root element. |
bindOnMDCTabSelectedEvent() => void | Adds MDCTab:selected event listener to root |
unbindOnMDCTabSelectedEvent() => void | Removes MDCTab:selected event listener from root |
registerResizeHandler(handler: EventListener) => void | Adds an event listener to the root element, for a resize event. |
deregisterResizeHandler(handler: EventListener) => void | Removes an event listener from the root element, for a resize event. |
getOffsetWidth() => number | Returns width of root element. |
setStyleForIndicator(propertyName: string, value: string) => void | Sets style property for indicator. |
getOffsetWidthForIndicator() => number | Returns width of indicator. |
notifyChange(evtData: Object) => void | Emits MDCTabBar:change event, passes evtData. |
getNumberOfTabs() => number | Returns number of tabs in MDC Tabs instance. |
getActiveTab() => MDCTab | Returns the instance of MDCTab that is currently active. |
isTabActiveAtIndex(index: number) => boolean | Returns true if tab at index is active. |
setTabActiveAtIndex(index: number) => void | Sets tab active at given index. |
isDefaultPreventedOnClickForTabAtIndex(index: number) => boolean | Returns true if tab does not prevent default click action. |
setPreventDefaultOnClickForTabAtIndex(index: number, preventDefaultOnClick: boolean) | Sets preventDefaultOnClick for tab at given index |
measureTabAtIndex(index: number) => void | sets measurements (width, left offset) for tab at given index. |
getComputedWidthForTabAtIndex(index: number) => number | Returns width of tab at given index. |
getComputedLeftForTabAtIndex(index: number) => number | Returns left offset of tab at given index. |
Sets layout for the Tab Bar component.
Returns index of currently active tab
Returns the width of the element containing the tabs.
Updates the active tab to be the tab at the given index, emits MDCTabBar:change
if shouldNotify
is true.
Returns the index of the currently active tab.
Property Name | Type | Description |
---|---|---|
tabBar | MDCTabBar | (read-only) The scroller's tab bar. |
Proxies to the foundation's layout()
method.
MDC Tab Bar Scroller ships with an MDCTabBarScrollerFoundation
class that external frameworks and libraries can use to integrate the component. As with all foundation classes, an adapter object must be provided.
Method Signature | Description |
---|---|
addClass(className: string) => void | Adds a class to the root element. |
removeClass(className: string) => void | Removes a class from the root element. |
eventTargetHasClass(target: HTMLElement, className: string) => boolean | Returns true if target has a given class name |
addClassToForwardIndicator(className: string) => void | Adds a given class to the forward indicator |
removeClassFromForwardIndicator(className: string) => void | Removes a given class from the forward indicator |
addClassToBackIndicator(className: string) => void | Adds a given class to the back indicator |
removeClassFromBackIndicator(className: string) => void | Removes a given class from the back indicator |
isRTL() => boolean | Returns true if in RTL context. False otherwise. |
registerBackIndicatorClickHandler(handler: EventListener) => void | Registers an event handler to be called when a click event happens on the back indicator |
deregisterBackIndicatorClickHandler(handler: EventHandler) => void | Deregisters an event handler from a click event happening on the back indicator |
registerForwardIndicatorClickHandler(handler: EventHandler) => void | Registers an event handler to be called when a click event happens on the forward indicator |
deregisterForwardIndicatorClickHandler(handler: EventHandler) => void | Deregisters an event handler from a click event happening on the forward indicator. |
registerCapturedInteractionHandler(evt: string, handler: EventHandler) => void | Registers an event handler to be called when a focus , touchstart , or mousedown event happens on the root of the component. These events gets dispatched to the listener during the capture phase. They also govern the scrolling behavior when tabs are tabbed to or actioned on. |
deregisterCapturedInteractionHandler(evt: string, handler: EventHandler) => void | Deregisters an event handler from a focus , touchstart , or mousedown events happening on the root of the component |
registerWindowResizeHandler(handler: EventHandler) => void | Registers an event handler to be called when a resize event happens on the window |
deregisterWindowResizeHandler(handler: EventHandler) => void | Deregisters an event handler from a resize event happening on the window |
getNumberOfTabs() => number | Returns the number of tabs in the scroller's tab bar |
getComputedWidthForTabAtIndex(index: number) => number | Returns the width of a tab at the given index |
getComputedLeftForTabAtIndex(index: number) => number | Returns the left offset of a tab at the given index |
getOffsetWidthForScrollFrame() => number | Returns the width of the scroll frame. This is the width of the visible tabs. |
getScrollLeftForScrollFrame() => number | Returns the scrollLeft value of the scroll frame |
setScrollLeftForScrollFrame(scrollLeftAmount: number) => void | Sets the value of scrollLeft for the scroll frame. |
getOffsetWidthForTabBar() => number | Returns the width of the entire tab bar, including that which is occluded. |
setTransformStyleForTabBar(value: string) => void | Sets the translateX transform property for the tab bar. |
getOffsetLeftForEventTarget(target: HTMLElement) => number | Returns the left offset of a given element. |
getOffsetWidthForEventTarget(target: HTMLElement) => number | Returns the width of a given element. |
Scrolls the tab bar such that the leftmost tab traverses the scroll frame and becomes the rightmost tab, potentially being partially, but not fully, occluded.
Scrolls the tab bar such that the rightmost tab traverses the scroll frame and becomes the leftmost tab. This tabs left offset will line up with the left edge of the scroll frame, and never be partially or fully occluded.
NOTE: Due to a quirk in event behavior, we allow the rightmost tab to be partially occluded even when tabbed to because clicking on such an element would shift the frame on the
focus
event. This would result in a scenario where the ripple persists and the intended tab would not be selected due to the tab bar shifting before themouseup
orclick
events get dispatched.
If the tab bar is overflowing its available width, this method will reset the back and forward indicators to the correct states (visible/hidden) based on the new width.
FAQs
The Material Components for the web tabs component
The npm package @material/tabs receives a total of 2,476 weekly downloads. As such, @material/tabs popularity was classified as popular.
We found that @material/tabs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 13 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.